package com.biodiv.miracle.ioc.context;

import com.biodiv.miracle.ioc.BeanDefinition;
import com.biodiv.miracle.ioc.factory.DefaultBeanFactory;
import com.biodiv.miracle.ioc.factory.FactoryBeanRegister;
import com.biodiv.miracle.ioc.scanner.ClasspathScanner;
import com.biodiv.miracle.event.EventObject;
import com.biodiv.miracle.support.annotation.Import;
import com.biodiv.miracle.support.utils.AnnotationUtils;
import com.biodiv.miracle.support.utils.MiracleUtils;
import com.biodiv.miracle.ioc.scanner.SPIResourceLoader;

import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;


/**
 * @Author: tianquan
 * @date: 2024-09-28  22:31
 * @Description: 通用上下文容器
 */
public class GeneralApplicationContext extends AbstractApplicationContext {

    private final Logger logger = Logger.getLogger(GeneralApplicationContext.class.getName());
    private final ClasspathScanner classpathScanner = new ClasspathScanner();
    protected final List<FactoryBeanRegister> factoryBeanRegisters;

    public GeneralApplicationContext() {
        factoryBeanRegisters = new ArrayList<>();
        MiracleUtils.init(this);
    }

    @Override
    public Object getBean(String name) {
        return beanFactory.getBean(name);
    }

    @Override
    public <T> T getBean(Class<T> aClass) {
        return beanFactory.getBean(aClass);
    }

    @Override
    public boolean containsBean(Class<?> aClass) {
        return beanFactory.containsBean(aClass);
    }

    @Override
    public <T> List<T> getBeans(Class<T> aClass) {
        return beanFactory.getBeans(aClass);
    }

    @Override
    public <A extends Annotation> List<Object> getBeanByAnnotation(Class<A> aClass) {
        return beanFactory.getBeanByAnnotation(aClass);
    }

    @Override
    public boolean containsBean(String name) {
        return beanFactory.containsBean(name);
    }

    @Override
    public boolean removeBeanDefinition(String name) {
        return beanFactory.removeBeanDefinition(name);
    }

    @Override
    public void registerBean(String name, Object bean) {
        BeanDefinition beanDefinition = new BeanDefinition(name, bean.getClass(), "singleton");
        beanFactory.registerBeanDefinition(name, beanDefinition);
        beanFactory.registerBean(name, bean);
    }

    @Override
    public void close() {
        beanFactory.clean();
    }

    @Override
    public void publishEvent(EventObject eventObject) {
        eventSourceManager.publishEvent(eventObject);
    }

    /**
     * 加载指定包路径下的所有类
     *
     * @param packageName 包的路径
     * @return 返回找到的所有类的列表
     */
    @Override
    public List<Class<?>> loadClass(String packageName) {
        return classpathScanner.loadClass(packageName);
    }

    @Override
    public String getEnvironmentVariable(String name) {
        return classpathScanner.getEnvironmentVariable(name);
    }

    @Override
    public InputStream getResource(String resourcePath) {
        return classpathScanner.getResource(resourcePath);
    }

    @Override
    public String getResourceAsString(String resourcePath) {
        return classpathScanner.getResourceAsString(resourcePath);
    }

    protected List<Class<?>> loadClass(Class<?> clazz) {
        return loadClass(clazz.getPackageName());
    }

    @Override
    protected List<Class<?>> findClassesInPackageAndSubpackages() {
        return loadClass(clazz);
    }

    protected void addBeanRegister(Class<?> clazz) {
        try {
            Object beanRegister = clazz.newInstance();
            factoryBeanRegisters.add((FactoryBeanRegister) beanRegister);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
